<?php

/**
 * @version    $Id: db.class.php 1 2016-07-19 08:45:53Z tic $
 */

if(!defined('IN_SYS')) exit('Access Denied');

class db{
	static $db,$sqls;
	static function init(){
		if(!isset(self::$db)){
			return self::$db = new mysql();
		}else{
			return self::$db;
		}
	}

	static function esc($string){
		return self::init()->esc($string);
	}

	static function setquery($sql){
		return self::init()->setquery($sql);
	}

	static function query($sql){
		return self::init()->query($sql);
	}

	static function fetch($queryID=false,$type=MYSQLI_ASSOC){
		return self::init()->fetch($queryID,$type=MYSQLI_ASSOC);
	}

	static function select($sql, $key=''){
		if(preg_match('/cache\s*(\d*)\s*$/i', $sql, $mt)){
			$sql = preg_replace('/cache\s*(\d*)\s*$/i', '', $sql);
			$data = cache::get(md5($sql.$key));
			if(is_array($data)){
				return $data;
			}
		}
		$data = self::init()->select($sql, $key);
		if(!empty($mt[1])){
			cache::set(md5($sql.$key), $data, $mt[1]);
		}
		return $data;
	}

	static function find($sql,$limit=true){
		$limit_str = $limit==true?'':'not';
		if(preg_match('/cache\s*(\d*)\s*$/i', $sql, $mt)){
			$sql = preg_replace('/cache\s*(\d*)\s*$/i', '', $sql);
			$data = cache::get(md5($sql.$limit_str));
			if(is_array($data)){
				return $data;
			}
		}
		$data = self::init()->find($sql,$limit=true);
		if(!empty($mt[1])){
			cache::set(md5($sql.$limit_str), $data, $mt[1]);
		}
		return $data;
	}

	static function getfield($sql,$limit=true){
		$limit_str = $limit==true?'':'not';
		if(preg_match('/cache\s*(\d*)\s*$/i', $sql, $mt)){
			$sql = preg_replace('/cache\s*(\d*)\s*$/i', '', $sql);
			if($data = cache::get(md5($sql.$limit_str))){
				return $data;
			}
		}
		$data = self::init()->getfield($sql,$limit);
		if(!empty($mt[1])){
			cache::set(md5($sql.$limit_str), $data, $mt[1]);
		}
		return $data;
	}

	static function sqls(){
		return self::init()->sqls;
	}

	static function getlastsql(){
		return self::init()->getlastsql();
	}

	static function insert_id(){
		return self::init()->insert_id();
	}

	static function affected_rows() {
		return self::init()->affected_rows();
	}
	
	static function close() {
		return self::init()->close();
	}
	
	static function free_result($queryID=false){
		return self::init()->free_result($queryID);
	}
	
	static function version() {
		return self::init()->version();
	}
	
	static function error() {
		return self::init()->error();
	}
	
	static function errno() {
		return self::init()->errno();
	}

	static function data($data){
		set_gpc($data);
	}
    
    static function table_exist($table) {
        return self::init()->table_exist($table);
    }

        static function save($table){
		$request = array_merge($_GET, $_POST);
		$rs = self::select("SHOW COLUMNS FROM `$table` cache 3600");
		foreach($rs as $r){
			if($r['Key'] == 'PRI'){
				$primary = $r['Field'];
				break;
			}
		}
		if( isset($request[$primary]) && self::find("select `$primary` from `$table` where `$primary`='{$request[$primary]}' ") ){
			$value = gpc($primary);
			$where = "`$primary`='$value'";
			$data = array();
			foreach($rs as $row){
				$fieldname = $row['Field'];
				if(isset($request[$fieldname])){
					$data[] = "`$fieldname` = '".$request[$fieldname]."'";
				}
			}
			if(count($data)>0){
				$sql = "update `$table` set ".join(",",$data)." where ".$where;	
				return self::query($sql);
			}
		}else{
			$fields = $values = array();
			foreach($rs as $row){
				$fieldname = $row['Field'];
				if(isset($request[$fieldname])){
					$fields[] = "`$fieldname`";
					$values[] = "'".$request[$fieldname]."'";
				}
			}
			if(count($fields)>0){
				$sql = "insert into `$table` (".join(',',$fields).") values (".join(',',$values).") ";
				self::query($sql);
				return self::insert_id();
			}
		}
	}
}

class mysql{
	public $dbhost,$dbname,$dbuser,$dbpassword;
	public $init,$link,$sql,$queryID,$sqls=array();
	
	public function __construct() {
		global $dbhost,$dbuser,$dbpassword,$dbname;
		list($this->dbhost, $this->port) = explode(":", $dbhost);
		$this->dbname = $dbname;
		$this->dbuser = $dbuser;
		$this->dbpassword = $dbpassword;
	}
	
	public function init() {
		if(!function_exists('mysqli_init')) $this->halt('ERROR : mysqli_init not exists');
		$this->link = mysqli_init();
		$this->init = mysqli_real_connect($this->link, $this->dbhost, $this->dbuser, $this->dbpassword, false, $this->port);
		if(mysqli_connect_errno()){
			$this->halt(mysqli_connect_error());
		}
		$version = mysqli_get_server_info($this->link);
		if($version < '5.0'){
			$this->halt('mysql version must above 5.0');
		}
		mysqli_query($this->link, "SET character_set_connection='utf8',character_set_results='utf8',character_set_client=binary,sql_mode=''");
		if(!mysqli_select_db($this->link, $this->dbname)) $this->halt('Cannot select database');
		return $this->link;
	}
	
	public function esc($string){
		if(!$this->init) {
			$this->init();
		}
		return mysqli_real_escape_string($this->link, $string );
	}

	public function setquery($sql) {
		$this->sql = $sql;
	}
	
	public function query($sql){
		if(!$this->init) {
			$this->init();
		}
		$this->setquery($sql);
		$start = microtime(TRUE);
		$this->queryID = mysqli_query($this->link, $this->sql) OR $this->halt();
		$needtime = number_format(microtime(TRUE) - $start, 6);
		if((!defined('ADMIN') && $needtime>0.3) || (defined('ADMIN') && $needtime>0.6)){
			error_log('<?php exit;?>'.$needtime.' | '.($this->sql)."\r\n", 3, DATA.'/log/sql_long_'.date("Y-m-d").'.php');
		}
        if(count($this->sqls)>=100) {
            array_shift($this->sqls);
        }
		$this->sqls[] = array('time'=>$needtime,'sql'=>$this->sql);
		return $this->queryID;
	}

	public function fetch($queryID=false,$type=MYSQLI_ASSOC){
		if(false===$queryID) $queryID = $this->queryID;
		return mysqli_fetch_array($queryID, $type);
	}
	
	public function select($sql, $key=''){
		$this->query($sql);
		$list = array();
		while($rs = $this->fetch()){
			if($key){
				$list[$rs[$key]] = $rs;
			}else{
				$list[] = $rs;
			}
		}
		$this->free_result();
		return $list;
	}
	
	public function find($sql,$limit=true){
		if($limit===true){
			if(stripos($sql,'limit')===false) $sql = rtrim($sql,';').' limit 1;';
		}
		$this->query($sql);
		$rs = $this->fetch();
		$this->free_result();
		return $rs;
	}
	
	public function getfield($sql,$limit=true){
		$result = $this->find($sql,$limit);
		return is_array($result)?array_pop($result):$result;
	}
	
	public function getlastsql(){
		return $this->sql;
	}
	
	public function insert_id() {
		return mysqli_insert_id($this->link);
	}
	
	public function affected_rows() {
		return mysqli_affected_rows($this->link);
	}
	
	public function close() {
		mysqli_close($this->link);
		$this->init = false;
	}
	
	public function free_result($queryID=false){
		if(false===$queryID) $queryID = $this->queryID;
		mysqli_free_result($queryID);
	}
	
	public function version() {
		return mysqli_get_server_info($this->link);
	}
	
	public function error() {
		return $this->init ? mysqli_error($this->link) : '';
	}
	
	public function errno() {
		return intval($this->init ? mysqli_errno($this->link) : '');
	}
	
	public function halt($msg=''){
		if($msg){
			throw new Exception($msg); 
		}else{
			throw new Exception("数据库发生错误<br>".$this->error()); 
		}
		exit;
	}
    
    public function table_exist($tables) {
        $dd = $this->query("SHOW TABLES LIKE '{$tables}'");
        if($dd->num_rows>0) {
            return true;
        }else {
            return false;
        }
    }
	
}

?>